import { _decorator, Node, Button } from 'cc';
import { BasePanel } from '../../../../scripts/libs/ui/BasePanel';
import { udm } from '../../../../scripts/managers/UserDataManager';
import { BindButton } from '../../../../scripts/libs/rxjs/cc3/BindButton';
import { SavingPotPanel } from '../SavingPotPanel/SavingPotPanel';
import { StageChestPanel } from '../StageChestPanel/StageChestPanel';
import { gm } from '../../../../scripts/managers/GameManager';
import { RemoveAdsPanel } from '../RemoveAdsPanel/RemoveAdsPanel';
import { Observable, of, Subscription } from 'rxjs';
import { ResourceHelper } from '../../ResourceHelper';
import { lm } from '../../LobbyManager';
import { KeyDown } from '../../../../scripts/libs/rxjs/cc3/KeyEvent';
import { KeyCode } from 'cc';
import { PlayfabDebugPanel } from '../PlayfabDebugPanel/PlayfabDebugPanel';
import { DailyTaskPanel } from '../DailyTaskPanel/DailyTaskPanel';
import { LuckyWheelPanel } from '../LuckyWheelPanel/LuckyWheelPanel';
import { PageView } from 'cc';
import { find } from 'cc';
import { nullifySubscription } from '../../../../scripts/libs/rxjs/utils';
import { CCBindPageView } from '../../../../scripts/libs/rxjs/cc3/BindPageView';
import { linear, linearClamp } from '../../../../scripts/libs/utils/math';
import { DesignWidth } from '../../../../scripts/managers/ScreenManager';
import { Label } from 'cc';
import { ProgressBar } from 'cc';
import { DevConfig } from '../../../../scripts/managers/DevConfig';
import { FlowStatus } from '../../Enums';
import { BuyHeartPanel } from '../BuyHeartPanel/BuyHeartPanel';
import { LeaderboardPage } from './LeaderboardPage/LeaderboardPage';
import { ShopPage } from './ShopPage/ShopPage';
import { thinking_sdk_m } from '../../../../scripts/managers/SDK/ThinkingCocosSDKManager';
import { v3 } from 'cc';
import { Vec3 } from 'cc';
import { StarterPackPanel } from '../StarterPackPanel/StarterPackPanel';
import { IapProductInfo } from '../../../../scripts/managers/SDK/IapSDKManager';
import { notification_sdk_m } from '../../../../scripts/managers/SDK/NotificationCocosSDKManager';
const { ccclass, property } = _decorator;

@ccclass('LobbyPanel')
export class LobbyPanel extends BasePanel {

    @property(PageView)
    pageView: PageView = null;

    @property(Button)
    startButton: Button = null;

    @property(Node)
    startButtonNode: Node = null;

    @property(Node)
    leftNode: Node = null;

    @property(Node)
    rightNode: Node = null;

    @property(Button)
    savingPotButton: Button = null;

    @property(Button)
    stageChestButton: Button = null;

    @property(Button)
    removeAdsButton: Button = null;

    @property(Button)
    dailyTaskButton: Button = null;

    @property(Button)
    luckyWheelButton: Button = null;

    @property(Button)
    starterPackButton: Button = null;

    @property(Button)
    lobbyShopButton: Button = null;

    @property(Button)
    lobbyHomeButton: Button = null;

    @property(Button)
    lobbyLeaderboardButton: Button = null;

    @property(Node)
    selectedBgNode: Node = null;

    @property(LeaderboardPage)
    leaderboardPage: LeaderboardPage = null;

    @property(ShopPage)
    shopPage: ShopPage = null;

    willBind(): void {
        // applovin_sdk_m.bannerShowReasons.add('default');
        this.adaptive();
    }

    useObserves() {
        return [
            udm.stageNum.subscribe(this.stageNumChanged.bind(this)),
            gm.stageInfo.subscribe(this.stageInfoChanged.bind(this)),
            udm.savingPot.subscribe(this.savingPotChanged.bind(this)),

            BindButton(this.startButton).subscribe(this.startButtonClicked.bind(this)),
            BindButton(this.savingPotButton).subscribe(this.savingPotButtonClicked.bind(this)),
            BindButton(this.stageChestButton).subscribe(this.stageChestButtonClicked.bind(this)),
            BindButton(this.removeAdsButton).subscribe(this.removeAdsButtonClicked.bind(this)),
            BindButton(this.luckyWheelButton).subscribe(this.luckyWheelButtonClicked.bind(this)),
            BindButton(this.dailyTaskButton).subscribe(this.dailyTaskButtonClicked.bind(this)),
            BindButton(this.starterPackButton).subscribe(this.starterPackButtonClicked.bind(this)),

            KeyDown().subscribe((_: KeyCode) => {
                if (!gm.editEnabled.value) {
                    if (_ == KeyCode.KEY_P) {
                        PlayfabDebugPanel.StartProcess().subscribe();
                    }
                }
            }),
            BindButton(this.lobbyShopButton).subscribe(this.lobbyShopButtonClicked.bind(this)),
            BindButton(this.lobbyHomeButton).subscribe(this.lobbyHomeButtonClicked.bind(this)),
            BindButton(this.lobbyLeaderboardButton).subscribe(this.lobbyLeaderboardButtonClicked.bind(this)),

            CCBindPageView(this.pageView).subscribe(this.pageViewHandler.bind(this)),

            gm.lobbyScrollToShopCommand.subscribe(this.lobbyShopButtonClicked.bind(this)),

            udm.noAds.subscribe(this.noAdsChanged.bind(this)),

            udm.iapStat.subscribe(this.iapStatChanged.bind(this)),

        ];
    }

    adaptive() {
        let scaleV3 = v3(Vec3.ONE).multiplyScalar(lm.getAdaptiveScale());
        this.startButtonNode.setScale(scaleV3);
        this.leftNode.setScale(scaleV3);
        this.rightNode.setScale(scaleV3);
    }

    willOpen(): Observable<string> {
        this.pageView.scrollToPage(1, 0);
        return new Observable(observer => {
            if (gm.stageInfo.value.stageId != udm.stageNum.value) {
                let targetStageId = udm.stageNum.value;
                lm.customLoadingReasons.add('load_stage');
                ResourceHelper.LoadStageAssets(targetStageId).subscribe(stageInfo => {
                    if (stageInfo != null) {
                        lm.customLoadingReasons.delete('load_stage');
                        if (stageInfo.stageId != null && stageInfo.stageId != targetStageId) {
                            this.warn('StageId in json is not match with stageId in file name.');
                            return;
                        }
                        stageInfo.stageId = targetStageId;
                        gm.stageInfo.value = stageInfo;
                    } else {
                        lm.customLoadingReasons.delete('load_stage');
                    }
                    observer.nextAndComplete();
                });
            } else {
                observer.nextAndComplete(null);
            }
        });
    }

    afterOpen(): Observable<string> {
        this.pageViewHandler({ state: 'scrolling' });
        // this.tryPopupPanel();

        if (gm.stageInfo.value.stageId >= DevConfig.REQUEST_NOTIFICATION_GREATEREQUAL_STAGE_NUM) {
            notification_sdk_m.requestPermission();
            udm.scheduleNotification();
        }

        return of(null);
    }

    onDestroyView(): void {
        nullifySubscription.call(this, '_sub_locker_anim');
    }

    starterIapProductInfo: IapProductInfo = null;
    iapStatChanged() { // 判断新手礼包入口按钮是否应该存在
        let list = Object.values(DevConfig.iap).filter(_ => _.giftType == 'newbie');
        let has = false;
        this.starterIapProductInfo = null;
        for (let i = 0; i < list.length; i++) {
            let info = list[i];
            if ((udm.iapStat.value[info.productId]?.buyNum ?? 0) < (info.limited ?? Infinity)) {
                this.starterIapProductInfo = info;
                has = true;
                break;
            }
        }
        this.starterPackButton.node.active = has;
    }

    noAdsChanged() {
        this.removeAdsButton.node.active = !udm.noAds.value;
    }

    stageNumChanged() {
        // this.startButton.stageId.value = udm.stageNum.value;
        find('Label', this.startButton.node).getComponent(Label).string = `LEVEL ${udm.stageNum.value}`;
    }

    stageInfoChanged() {
        let progressBar = find('ProgressBar', this.stageChestButton.node).getComponent(ProgressBar);
        let progressLabel = find('progressLabel', progressBar.node).getComponent(Label);

        let { chestCurValue, chestMaxValue, flag } = udm.checkStageChestProgress(gm.stageInfo.value.stageId, false);
        let progress = chestCurValue / chestMaxValue;
        progressBar.progress = progress;
        progressLabel.string = `${chestCurValue}/${chestMaxValue}`;
    }

    savingPotChanged() {
        let progressBar = find('ProgressBar', this.savingPotButton.node).getComponent(ProgressBar);
        let progressLabel = find('progressLabel', progressBar.node).getComponent(Label);
        let progress = (udm.savingPot.value.coin ?? 0) / DevConfig.SAVING_POT.COIN_CAPACITY;
        progressBar.progress = progress;
        progressLabel.string = `${udm.savingPot.value.coin ?? 0}/${DevConfig.SAVING_POT.COIN_CAPACITY}`;
    }

    // shopPopupButtonClicked() {
    //     thinking_sdk_m.requestTrack('Shoping_Open', {
    //         OpenType: 'Icon',
    //         OpenWay: 'Home',
    //         IsNew: udm.isNew.value,
    //         Level_ID: udm.stageNum.value,
    //     });
    //     ShopPanel.StartProcess().subscribe();
    // }

    startButtonClicked() {
        lm.customLoadingReasons.add('load_stage');
        ResourceHelper.LoadStageAssets(udm.stageNum.value).subscribe(stageInfo => {
            if (stageInfo != null) {
                lm.customLoadingReasons.delete('load_stage');
                if (stageInfo.stageId != null && stageInfo.stageId != udm.stageNum.value) {
                    this.warn('StageId in json is not match with stageId in file name.');
                    return;
                }
                stageInfo.stageId = udm.stageNum.value;
                gm.stageInfo.value = stageInfo;
                if (gm.editEnabled.value) {
                    lm.flowStatus.value = FlowStatus.EditorGame;
                } else {
                    let curHeartCount = udm.getHeartCount();
                    if (udm.getRemainMsToOverInfHeart() > 0 || curHeartCount > 0) {
                        lm.flowStatus.value = FlowStatus.Game;
                    } else {
                        BuyHeartPanel.StartProcess((panel: BuyHeartPanel) => {
                            panel.openWay = 'Home';
                        }).subscribe(_ => {
                            if (_ == 'continue') {
                                lm.flowStatus.value = FlowStatus.Game;
                            }
                        });
                    }
                }
            } else {
                lm.customLoadingReasons.delete('load_stage');
            }
        });
    }

    savingPotButtonClicked() {
        SavingPotPanel.StartProcess().subscribe();
    }

    stageChestButtonClicked() {
        StageChestPanel.StartProcess((panel: StageChestPanel) => {
            panel.stageInfo.value = gm.stageInfo.value;
        }).subscribe();
    }

    removeAdsButtonClicked() {
        RemoveAdsPanel.StartProcess().subscribe();
        thinking_sdk_m.requestTrack('NoAds_Open', {
            Type: 'Icon',
            Level_ID: udm.stageNum.value,
            IsNew: udm.isNew.value,
        });
    }

    dailyTaskButtonClicked() {
        DailyTaskPanel.StartProcess().subscribe();
    }

    luckyWheelButtonClicked() {
        LuckyWheelPanel.StartProcess().subscribe();
    }

    starterPackButtonClicked() {
        if (this.starterIapProductInfo != null) {
            StarterPackPanel.StartProcess((panel: StarterPackPanel) => {
                panel.data.value = this.starterIapProductInfo;
            }).subscribe();
        }
    }

    // leaderboardButtonClicked() {
    //     LeaderboardPanel.StartProcess().subscribe();
    // }

    lobbyShopButtonClicked() {
        this.log('shopButtonClicked');
        this.pageView.setCurrentPageIndex(0);
    }

    lobbyHomeButtonClicked() {
        this.log('homeButtonClicked');
        this.pageView.setCurrentPageIndex(1);
    }

    _sub_locker_anim: Subscription = null;
    lobbyLeaderboardButtonClicked() {
        this.log('lobbyLeaderboardButtonClicked');
        this.pageView.setCurrentPageIndex(2);
        // nullifySubscription.call(this, '_sub_locker_anim');
        // this.log('lockerButtonClicked')
        // AnimationPlay(find('icon', this.lobbyLeaderboardButton.node).getComponent(Animation), 'locker_shake').subscribe()
    }

    pageViewHandler(param: { state: string }) {
        if (param.state == 'scrolling') {
            // this.log('@pageViewHandler');
            let buttonWidth = DesignWidth / 3;
            let buttonX0 = -buttonWidth;
            let buttonX1 = 0;
            let buttonX2 = buttonWidth;

            let contentX = this.pageView.content.position.x;
            let selectX = linear(-540, -1620, buttonX0, buttonX1, contentX);
            this.selectedBgNode.setPosition(selectX, -10, 0);

            let diffX0 = Math.abs(selectX - buttonX0);
            let scale0 = linearClamp(0, buttonWidth, 1, .7, diffX0);
            find('icon', this.lobbyShopButton.node).setScale(scale0, scale0, scale0);
            let y0 = linearClamp(0, buttonWidth, 40, 0, diffX0);
            find('icon', this.lobbyShopButton.node).setPosition(0, y0, 0);

            let diffX1 = Math.abs(selectX - buttonX1);
            let scale1 = linearClamp(0, buttonWidth, 1, .7, diffX1);
            find('icon', this.lobbyHomeButton.node).setScale(scale1, scale1, scale1);
            let y1 = linearClamp(0, buttonWidth, 40, 0, diffX1);
            find('icon', this.lobbyHomeButton.node).setPosition(0, y1, 0);

            let diffX2 = Math.abs(selectX - buttonX2);
            let scale2 = linearClamp(0, buttonWidth, 1, .7, diffX2);
            find('icon', this.lobbyLeaderboardButton.node).setScale(scale2, scale2, scale2);
            let y2 = linearClamp(0, buttonWidth, 40, 0, diffX2);
            find('icon', this.lobbyLeaderboardButton.node).setPosition(0, y2, 0);

            gm.diffX2.value = diffX2;

            if (diffX2 < buttonWidth - 2) {
                this.leaderboardPage.scrollView.node.active = true;
                if (!this.leaderboardPage.scrollViewDidOpen) {
                    this.leaderboardPage.openScrollView();
                }
            } else {
                this.leaderboardPage.scrollView.node.active = false;
            }

            if (diffX0 < buttonWidth - 2) {
                if (this.shopPage.scrollView.node.active == false) {
                    thinking_sdk_m.requestTrack('Shoping_Open', {
                        OpenType: 'Icon',
                        OpenWay: 'Home',
                        IsNew: udm.isNew.value,
                        Level_ID: udm.stageNum.value,
                    });
                    if (this.shopPage.freeAdsAvailable()) {
                        gm.currentAdsType.value = 'AdGiveCoin';
                        gm.currentAdsOpenUI.value = 'ShopPanel';
                        thinking_sdk_m.requestTrack('Ads_Show', {
                            AdsType: 'AdGiveCoin',
                            OpenUI: 'ShopPanel',
                            IsNew: udm.isNew.value
                        });
                    }
                }
                this.shopPage.scrollView.node.active = true;
                this.shopPage.tryScrollToTop();
            } else {
                this.shopPage.scrollView.node.active = false;
            }
        }
    }

    tryPopupPanel() {
        let autoPopupRemoveAds = (udm.noAds.value ?? 0) == 0;
        let autoPopupStarterPack = this.starterIapProductInfo != null;
        let autoPopupSavingPot = udm.savingPot.value.autoPopup ?? false;

        let cand = [];//['removead, starterpack, savingpot'];

        if ([3, 10].includes(gm.lastWinStageNum.value)) {
            cand.push('savingpot');
        } else if (gm.lastWinStageNum.value == 7) {
            if (autoPopupRemoveAds) {
                cand.push('removead');
            }
        } else if (gm.lastWinStageNum.value == 12) {
            if (autoPopupStarterPack) {
                cand.push('starterpack');
            }
        } else if (gm.lastWinStageNum.value >= 13) {
            if ((gm.lastWinStageNum.value - 1) % 3 == 0) { // 13,16,19...
                let order = Math.floor((gm.lastWinStageNum.value - 13) / 3);
                if (order % 2 == 0) {
                    if (autoPopupRemoveAds) cand.push('removead');
                    if (autoPopupStarterPack) cand.push('starterpack');
                } else {
                    if (autoPopupStarterPack) cand.push('starterpack');
                    if (autoPopupRemoveAds) cand.push('removead');
                }
            }
            if (autoPopupSavingPot) {
                cand.push('savingpot');
            }
        }

        if (cand.length > 0) {
            if (cand[0] == 'savingpot') {
                udm.savingPot.value.autoPopup = false;
                udm.save();
                SavingPotPanel.StartProcess().subscribe();
            } else if (cand[0] == 'removead') {
                RemoveAdsPanel.StartProcess().subscribe();
                thinking_sdk_m.requestTrack('NoAds_Open', {
                    Type: 'Other',
                    Level_ID: udm.stageNum.value,
                    IsNew: udm.isNew.value,
                });
            } else if (cand[0] == 'starterpack') {
                StarterPackPanel.StartProcess((panel: StarterPackPanel) => {
                    panel.data.value = this.starterIapProductInfo;
                }).subscribe();
            }
        }

        gm.lastWinStageNum.value = null;
    }

}

